package com.yixueyun.ucenter.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yixueyun.ucenter.mapper.YxyUserMapper;
import com.yixueyun.ucenter.mapper.YxyUserRoleMapper;
import com.yixueyun.ucenter.model.dto.AuthParamsDto;
import com.yixueyun.ucenter.model.dto.YxyUserExt;
import com.yixueyun.ucenter.model.po.YxyUser;
import com.yixueyun.ucenter.model.po.YxyUserRole;
import com.yixueyun.ucenter.service.AuthService;
import com.yixueyun.ucenter.service.WxAuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.UUID;

/**
 * 微信认证处理接口
 */
@Slf4j
@Service("wx_authservice")
public class WxAuthServiceImpl implements AuthService, WxAuthService {
    @Autowired
    RestTemplate restTemplate;
    @Value("${weixin.appid}")
    String appid;
    @Value("${weixin.secret}")
    String secret;
    @Autowired
    WxAuthServiceImpl currentPorxy;
    @Autowired
    private YxyUserMapper yxyUserMapper;
    @Autowired
    private YxyUserRoleMapper yxyUserRoleMapper;
    @Override
    public YxyUserExt execute(AuthParamsDto authParamsDto) {
        //查询数据库
        String username = authParamsDto.getUsername();
        YxyUser yxyUser = yxyUserMapper.selectOne(new LambdaQueryWrapper<YxyUser>().eq(YxyUser::getUsername, username));
        if(yxyUser == null) {
            throw new RuntimeException("用户不存在！");
        }
        YxyUserExt yxyUserExt = new YxyUserExt();
        BeanUtils.copyProperties(yxyUser, yxyUserExt);
        return yxyUserExt;
    }
    /**
     * 微信认证：申请令牌，携带令牌查询用户信息，报错用户信息到数据库
     * @param code 授权码
     * @return
     */
    @Override
    public YxyUser wxAuth(String code) {
        //1.申请令牌
        Map<String, String> accessToken_map = getAccess_token(code);
        String accessToken = accessToken_map.get("access_token");
        String openid = accessToken_map.get("openid");
        //携带令牌查询用户信息
        Map<String, String> userinfo = getUserinfo(accessToken, openid);
        System.out.println(userinfo);
        //报错用户信息到数据库
        YxyUser yxyUser = currentPorxy.addWxUser(userinfo);
        return yxyUser;
    }
    /**
     * 申请访问令牌,响应示例
     {
     "access_token":"ACCESS_TOKEN",
     "expires_in":7200,
     "refresh_token":"REFRESH_TOKEN",
     "openid":"OPENID",
     "scope":"SCOPE",
     "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
     }
     */
    private Map<String,String> getAccess_token(String code) {
        String url_template = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
        String url = String.format(url_template,appid,secret,code);
    //远程调用
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, null, String.class);
        //处理响应结果
        String result = exchange.getBody();
        Map<String,String> map = JSON.parseObject(result, Map.class);
        return map;
    }
    /**获取用户信息，示例如下：
     {
     "openid":"OPENID",
     "nickname":"NICKNAME",
     "sex":1,
     "province":"PROVINCE",
     "city":"CITY",
     "country":"COUNTRY",
     "headimgurl": "https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
     "privilege":[
     "PRIVILEGE1",
     "PRIVILEGE2"
     ],
     "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
     }
     */
    private Map<String,String> getUserinfo(String access_token,String openid) {
        String wxUrl_template = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s";
        //请求微信地址
        String wxUrl = String.format(wxUrl_template, access_token,openid);

        log.info("调用微信接口申请access_token, url:{}", wxUrl);

        ResponseEntity<String> exchange = restTemplate.exchange(wxUrl, HttpMethod.POST, null, String.class);

        //防止乱码进行转码
        String result = new String(exchange.getBody().getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);
        log.info("调用微信接口申请access_token: 返回值:{}", result);
        Map<String,String> resultMap = JSON.parseObject(result, Map.class);

        return resultMap;
    }

    /**
     * 向数据库写入信息
     * @param userInfo_map
     * @return
     */
    @Transactional
    public YxyUser addWxUser(Map<String,String> userInfo_map) {
        //1.查询数据库
        String unionid = userInfo_map.get("unionid");
        YxyUser yxyUser = yxyUserMapper.selectOne(new LambdaQueryWrapper<YxyUser>().eq(YxyUser::getWxUnionid, unionid));
        if(yxyUser != null) {
            return yxyUser;
        }
        //插入
        String userId = UUID.randomUUID().toString();
        yxyUser = new YxyUser();
        yxyUser.setId(userId);
        yxyUser.setWxUnionid(unionid);
        //记录从微信得到的昵称
        yxyUser.setNickname(userInfo_map.get("nickname").toString());
        yxyUser.setUserpic(userInfo_map.get("headimgurl").toString());
        yxyUser.setName(userInfo_map.get("nickname").toString());
        yxyUser.setUsername(unionid);
        yxyUser.setPassword(unionid);
        yxyUser.setUtype("101001");//学生类型
        yxyUser.setStatus("1");//用户状态
        yxyUser.setCreateTime(LocalDateTime.now());
        yxyUserMapper.insert(yxyUser);
        //向关系表中插入数据
        YxyUserRole yxyUserRole = new YxyUserRole();
        yxyUserRole.setId(UUID.randomUUID().toString());
        yxyUserRole.setUserId(userId);
        yxyUserRole.setRoleId("17");//学生角色
        yxyUserRoleMapper.insert(yxyUserRole);
        return yxyUser;
    }
}
